package tech.xs.common.framework.util;

import cn.hutool.core.codec.Base64;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import tech.xs.common.framework.domain.constant.HttpHeaderKey;
import tech.xs.common.framework.domain.constant.Symbol;
import tech.xs.common.auth.domain.enums.AuthClientTypeEnum;
import tech.xs.common.framework.domain.enums.AuthModeEnum;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

public class AuthHeaderUtil {


    @Getter
    @Setter
    @ToString
    public static class AuthHeader {
        private Long userId;
        private String userName;
        private String password;
        private AuthClientTypeEnum clientType;
        private String accessToken;
        private AuthModeEnum mode;
    }

    public static AuthHeader getTokenAuthHeader(String token) {
        if (token == null) {
            return null;
        }
        String[] arr = token.split(Symbol.HYPHEN_STR);
        if (arr.length < 3) {
            return null;
        }
        AuthHeader headToken = new AuthHeader();
        headToken.setMode(AuthModeEnum.Token);
        headToken.setAccessToken(token);
        headToken.setUserId(Long.parseLong(arr[0]));
        headToken.setClientType(AuthClientTypeEnum.create(Integer.parseInt(arr[1])));
        return headToken;
    }

    public static AuthHeader getBasicAuthHeader(String authorization) {
        authorization = Base64.decodeStr(authorization);
        String[] arr = authorization.split(Symbol.COLON_STR);
        if (arr.length < 2) {
            return null;
        }
        AuthHeader headToken = new AuthHeader();
        headToken.setMode(AuthModeEnum.Basic);
        headToken.setUserName(arr[0]);
        headToken.setPassword(arr[1]);
        return headToken;
    }

    public static AuthHeader getAuthHeader() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes == null) {
            return null;
        }
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        return getAuthHeader(request);
    }

    public static AuthHeader getAuthHeader(HttpServletRequest request) {
        String accessToken = request.getHeader(HttpHeaderKey.ACCESS_TOKEN);
        if (accessToken != null && !accessToken.isEmpty()) {
            return getTokenAuthHeader(accessToken);
        }

        String authorization = request.getHeader(HttpHeaderKey.AUTHORIZATION);
        return getAuthHeaderByAuthorization(authorization);
    }

    public static AuthHeader getAuthHeader(ServerHttpRequest request) {
        HttpHeaders headers = request.getHeaders();
        List<String> tokens = headers.get(HttpHeaderKey.ACCESS_TOKEN);
        if (tokens != null && !tokens.isEmpty()) {
            String accessToken = tokens.get(0);
            if (accessToken != null && !accessToken.isEmpty()) {
                return getTokenAuthHeader(accessToken);
            }
        }

        List<String> authorizations = headers.get(HttpHeaderKey.AUTHORIZATION);
        if (authorizations != null && !authorizations.isEmpty()) {
            return getAuthHeaderByAuthorization(authorizations.get(0));
        }
        return null;
    }

    public static AuthHeader getAuthHeaderByAuthorization(String authorization) {
        if (authorization == null) {
            return null;
        }
        if (authorization.isEmpty()) {
            return null;
        }
        String[] arr = authorization.split(Symbol.SPACE_STR);
        if (arr.length < 2) {
            return null;
        }
        if ("Basic".equals(arr[0])) {
            return getBasicAuthHeader(arr[1]);
        }
        return null;
    }


}
